package one.stand.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import one.stand.code.RedisCode;
import one.stand.config.CardPosterConfig;
import one.stand.entity.GoodsPosterEntity;
import one.stand.entity.websocket.CommodityInfoEntity;
import one.stand.enums.GoodAssembleStatusEnum;
import one.stand.enums.GoodKillStatusEnum;
import one.stand.enums.SeeRecordEnums;
import one.stand.model.*;
import one.stand.request.*;
import one.stand.response.CompanyResponse;
import one.stand.response.GoodSpecResponse;
import one.stand.response.GoodsResponse;
import one.stand.response.GoodstypeResponse;
import one.stand.service.CompanyAccontService;
import one.stand.service.GoodsService;
import one.stand.service.WxSunCodeService;
import one.stand.util.DateUtil;
import one.stand.util.OssUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author Administrator
 */
@Service
@Transactional
public class GoodsServiceImpl extends PublicBaseService implements GoodsService {

    private Logger logger = LoggerFactory.getLogger(GoodsServiceImpl.class);

    @Override
    public ResultModel getCompanyInfo(CompanyRequest request) {
        if(request == null && request.getCompanyId() == null){
            return ResultModel.checkParamFail("公司ID为空");
        }
        CompanyModel model = new CompanyModel();
        BeanUtils.copyProperties(request, model);
        CompanyModel companyModel = null;
        if(request.getId() == null){
            companyModel = companyMapper.selectByPrimaryKey(model.getCompanyId());
        } else {
            model.setMyUserId(request.getId().intValue());
            companyModel = companyMapper.selectCompanyGoodsType(model);
        }

        CompanyResponse companyResponse = new CompanyResponse();
        if (companyModel == null) {
            return ResultModel.noData();
        }
        BeanUtils.copyProperties(companyModel, companyResponse);
        return ResultModel.success(companyResponse);
    }

    @Override
    public ResultModel getGoodsType(GoodstypeRequest request) {
        if(request == null){
            return ResultModel.checkParamFail("商品类型请求为空");
        }
        GoodstypeModel model = new GoodstypeModel();
        BeanUtils.copyProperties(request, model);
        model.setUserId(request.getId().intValue());
        List<GoodstypeModel> list = goodstypeMapper.selectGoodsType(model);
        if (list == null || list.isEmpty()) {
            return ResultModel.noData();
        }
        List<GoodstypeResponse> responseList = new ArrayList<>();
        list.forEach(obj -> {
            {
                GoodstypeResponse response = new GoodstypeResponse();
                BeanUtils.copyProperties(obj, response);
                responseList.add(response);
            }
        });
        return ResultModel.success(responseList);
    }

    @Override
    public ResultModel getGoodsList(GoodsRequest request) {
        if(request == null){
            return ResultModel.checkParamFail("商品请求为空");
        }
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        GoodsModel model = new GoodsModel();
        BeanUtils.copyProperties(request, model);
        if(request.getGoodstypeId() == null || request.getGoodstypeId() <= 0){
            model.setGoodstypeId(null);
        }
        List<GoodsModel> list = goodsMapper.selectGoodsInfo(model);
        if (list == null || list.isEmpty()) {
            return ResultModel.noData();
        }

        if (request.getCId() == null || list.get(0).getCompanyId() != request.getCId().intValue()) {
            //添加查看记录
            //addSeeRecord(request.getId().intValue(), request.getCardId(), list.get(0).getCompanyId(), SeeRecordEnums.PRODUCT.getCode(), null, 1);
        }
        List<GoodsResponse> responseList = new ArrayList<>();
        //商品秒杀和拼团状态
        List<Integer> killGoodIdList = new ArrayList<>();
        List<Integer> assembleGoodIdList = new ArrayList<>();
        getKillOrAssembleGoodsIdList(list, killGoodIdList, assembleGoodIdList);
        Map<Integer, Integer> goodKillStatusMap = selectGoodKillStatus(killGoodIdList);
        Map<Integer, Integer> goodAssembleStatusMap = selectGoodAssembleStatus(assembleGoodIdList);
        list.forEach(obj -> {{
            GoodsResponse response = new GoodsResponse();
            BeanUtils.copyProperties(obj, response);
            if(goodKillStatusMap.get(response.getGoodsId()) != null){
                //真实秒杀,将最低金额设置到price上面
                if(GoodKillStatusEnum.KILLING.getCode() == goodKillStatusMap.get(response.getGoodsId())){
                    response.setIsKill(GoodKillStatusEnum.KILLING.getCode());
                    response.setKillPrice(response.getKillPrice());
                }else {
                    response.setIsKill(GoodKillStatusEnum.UN_KILL.getCode());
                }
            }else {
                response.setIsKill(GoodKillStatusEnum.UN_KILL.getCode());
            }
            if(goodAssembleStatusMap.get(response.getGoodsId()) != null){
                //真实拼团,判断是否拼团设置金额
                if(GoodAssembleStatusEnum.ASSEMBLE_ING.getCode() == goodAssembleStatusMap.get(response.getGoodsId())){
                    response.setIsAssemble(GoodAssembleStatusEnum.ASSEMBLE_ING.getCode());
                    response.setAssemblePrice(response.getAssemblePrice());
                }else {
                    response.setIsAssemble(GoodAssembleStatusEnum.UN_ASSEMBLE.getCode());
                }
            }else {
                response.setIsAssemble(GoodAssembleStatusEnum.UN_ASSEMBLE.getCode());
            }

            responseList.add(response);
        }});
        PageInfo<GoodsResponse> pageList = new PageInfo<>(responseList);
        return ResultModel.success(pageList.getList());
    }

    /**
     * 校验商品秒杀状态
     * @return
     */
    private Map<Integer, Integer> selectGoodKillStatus(List<Integer> killGoodIdList){
        Map<Integer, Integer> resultMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(killGoodIdList)){
            List<GoodsKillModel> goodKillList = goodsMapper.selectKillGoodsList(killGoodIdList);
            if(!CollectionUtils.isEmpty(goodKillList)){
                goodKillList.forEach(item->{
                    resultMap.put(item.getGoodsId(), item.getState());
                });
            }
        }
        return resultMap;
    }

    /**
     * 校验商品拼团状态
     * @return
     */
    private Map<Integer, Integer> selectGoodAssembleStatus(List<Integer> assembleGoodIdList){
        Map<Integer, Integer> resultMap = new HashMap<>();
        if(!CollectionUtils.isEmpty(assembleGoodIdList)){
            List<GoodsAssembleModel> assembleGoodList = goodsAssembleMapper.selectAssembleGoodList(assembleGoodIdList);
            if(!CollectionUtils.isEmpty(assembleGoodList)){
                assembleGoodList.forEach(item->{
                    resultMap.put(item.getGoodsId(), item.getState());
                });
            }
        }
        return resultMap;
    }

    /**
     * 获取秒杀/拼团商品状态
     * @param list
     * @return
     */
    private void getKillOrAssembleGoodsIdList(List<GoodsModel> list, List<Integer> killGoodIdList, List<Integer> assembleGoodIdList){
        List<Integer> goodsIdList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(list)){
            list.forEach(item->{
                //秒杀
                if(item.getIsKill() == 1){
                    killGoodIdList.add(item.getGoodsId());
                }
                //拼团
                if(item.getIsAssemble() == 1){
                    assembleGoodIdList.add(item.getGoodsId());
                }
            });
        }
    }

    @Override
    public ResultModel getGoodSpec(GoodSpecRequest request) {
        GoodSpecModel model = new GoodSpecModel();
        if (request != null) {
            BeanUtils.copyProperties(request, model);
        }
        List<GoodSpecModel> list = goodSpecMapper.getSpec(model);
        if (list == null || list.isEmpty()) {
            return ResultModel.noData();
        }
        List<GoodSpecResponse> responseList = new ArrayList<>();
        list.forEach(obj -> {{
            GoodSpecResponse response = new GoodSpecResponse();
            BeanUtils.copyProperties(obj, response);
            responseList.add(response);
        }});
        return ResultModel.success(responseList);
    }

    @Override
    public ResultModel getGoodsInfo(GoodsRequest request) {
        if(request == null || request.getGoodsId() == null){
            return ResultModel.checkParamFail("商品信息为空");
        }
        GoodsModel model = new GoodsModel();
        BeanUtils.copyProperties(request, model);
        model.setIsDel(0);
        List<GoodsModel> list = goodsMapper.getGoodsInfo(model);
        if (list == null || list.isEmpty()) {
            return ResultModel.noData();
        }
        log.info("查询商品详情请求: {}", JSON.toJSONString(request));
        boolean fal = request.getGoodsId() != null && (request.getCId() == null || list.get(0).getCompanyId() != request.getCId().intValue());
        if (fal) {
            //添加查看记录
            addSeeRecord(request.getId().intValue(), request.getCardId(), list.get(0).getCompanyId(), SeeRecordEnums.PRODUCT.getCode(), request.getGoodsId(), 0);
        }
        GoodsResponse response = new GoodsResponse();
        BeanUtils.copyProperties(list.get(0), response);
        //判断商品是否拼团或者秒杀
        List<GoodsModel> newModelList = new ArrayList<>();
        newModelList.add(list.get(0));
        List<Integer> killGoodIdList = new ArrayList<>();
        List<Integer> assembleGoodIdList = new ArrayList<>();
        getKillOrAssembleGoodsIdList(newModelList, killGoodIdList, assembleGoodIdList);
        Map<Integer, Integer> goodKillStatusMap = selectGoodKillStatus(killGoodIdList);
        Map<Integer, Integer> goodAssembleStatusMap = selectGoodAssembleStatus(assembleGoodIdList);
        // 当前商品为拼团商品
        if(validateGoodAssemble(list.get(0), goodAssembleStatusMap)){
            // 设置拼团活动 距离当前的结束时间
            GoodsAssembleModel assembleModel = new GoodsAssembleModel();
            assembleModel.setGoodsId(response.getGoodsId());
            assembleModel.setIsDel(0);
            GoodsAssembleModel goodsAssemble = goodsAssembleMapper.getGoodsAssemble(response.getGoodsId());
            if(goodsAssemble != null){
                response.setAssembleEndTime(DateUtil.getDifferTime(goodsAssemble.getEndTime(),new Date()));
            }
            // todo  用户拼团信息应该和当前商品最新的拼团配置绑定？此处应该只是查询当前活跃的拼团配置下的用户拼团信息？？
            // 设置商品已拼团信息集合
            List<AssembleModel> assembleModelList = assembleMapper.assembleModelList(request.getGoodsId());
            assembleModelList.forEach(am -> {
                am.setNickeName(getDecodeNickeName(am.getNickeName()));
                am.setAssembleEndTime(DateUtil.getDifferTime(am.getEndTime(), new Date()));
            });
            response.setAssembleModelList(assembleModelList);
            // 设置商品拼团配置
            response.setGoodsAssembleModel(goodsAssemble);
        }else {
            response.setIsAssemble(GoodAssembleStatusEnum.UN_ASSEMBLE.getCode());
            response.setAssemblePrice(0);
            //商品秒杀
            if(validateGoodKillStatus(list.get(0), goodKillStatusMap)){
                // 查询该商品的秒杀总销量
                Integer buyNum = secKillMapper.selectKillBuyNum(new SecKillModel() {{
                    setGoodsId(request.getGoodsId());
                }});
                buyNum = (buyNum == null) ? 0 : buyNum;
                // 设置秒杀剩余库存
                response.setGoodsNum(list.get(0).getKillNum() - buyNum);
                // 设置秒杀距离当前的结束时间
                SecKillModel secKillModel = secKillMapper.selectKillGoodsInfo(new SecKillModel() {{
                    setIsDel(0);
                    setGoodsId(response.getGoodsId());
                }});
                if(secKillModel != null){
                    response.setKillType(secKillModel.getKillType());
                    response.setKillEndTime(DateUtil.getDifferTime(secKillModel.getEndTime(),new Date()));
                }
            }else {
                response.setIsKill(GoodKillStatusEnum.UN_KILL.getCode());
                response.setKillType(null);
                response.setKillPrice(0);
            }
        }
        // TODO 设置该商品的秒杀销量
        return ResultModel.success(response);
    }

    /**
     * 校验商品秒杀状态
     * @param good
     * @return
     */
    private boolean validateGoodKillStatus(GoodsModel good, Map<Integer, Integer> goodKillStatusMap){
        if(goodKillStatusMap.get(good.getGoodsId()) != null){
            if(GoodKillStatusEnum.KILLING.getCode() == goodKillStatusMap.get(good.getGoodsId())){
                return true;
            }
        }
        return false;
    }

    /**
     * 校验商品拼团状态
     * @param good
     * @param goodAssembleStatusMap
     * @return
     */
    private boolean validateGoodAssemble(GoodsModel good, Map<Integer, Integer> goodAssembleStatusMap){
        if(goodAssembleStatusMap.get(good.getGoodsId()) != null){
            if(GoodKillStatusEnum.KILLING.getCode() == goodAssembleStatusMap.get(good.getGoodsId())){
                return true;
            }
        }
        return false;
    }


    @Autowired
    private CardPosterConfig cardPosterConfig;
    @Autowired
    private WxSunCodeService wxSunCodeService;
    @Autowired
    private CompanyAccontService companyAccontService;
    @Autowired
    private OssUtil ossUtil;
    @Override
    public ResultModel goodsCard(GoodSpecRequest request) {
        if(request.getSpecId()==null){
            return ResultModel.checkParamFail("specId: 不能为空");
        }
        CommodityInfoEntity commodityInfoEntity=goodSpecMapper.getSendMessage(request.getSpecId().longValue());
        if(null==commodityInfoEntity){
            return  ResultModel.fail("商品不存在");
        }
        String  sunCodeUrl = null;
        if(StringUtils.isBlank(sunCodeUrl)){
            // 从商品的company_id 查找company表中user_id，然后再查找user表中user_id对应数据的enterprise_id，最终确定真正小程序的company_id
            Integer companyId = companyMapper.selectEnterpriseIdByCompanyId(commodityInfoEntity.getCompanyId());
            CompanyAccountModel companyAccountModel= companyAccontService.selectByCompanyKeyDefault(new CompanyAccountRequest(){{
                setCompanyId(companyId);
                // 2020-01-04 解决商品分享太阳码问题。商品分享地址，选择名片appId生成太阳码，如果不加，有可能crm放在前面，取第一个就是crm的id
                setAccountType(1);
            }}) ;


            StringBuffer stringBuffer = new StringBuffer();
            //名片id
            stringBuffer.append("card=").append(businessCardMapper.getBoosCardId(commodityInfoEntity.getCompanyId()));
            //公司id
            stringBuffer.append("&c=").append(commodityInfoEntity.getCompanyId());
            //分类id
            stringBuffer.append("&s=").append(commodityInfoEntity.getSpecId());
            //商品id
            stringBuffer.append("&g=").append(commodityInfoEntity.getGoodsId());

            JSONObject paramJson = new JSONObject();
            paramJson.put("scene", stringBuffer);
            paramJson.put("page", goodsSunCode);
            log.info("商品太阳码参数：{}", paramJson.toJSONString());
            log.info("企业账号信息：{}", JSON.toJSONString(companyAccountModel));
            sunCodeUrl =wxSunCodeService.getWxCode(paramJson, companyAccountModel.getAppId(), companyAccountModel.getAppSecret());
            redisUtil.set(RedisCode.getGoodsSunCode(commodityInfoEntity.getGoodsId()), sunCodeUrl);
        }
        log.info("生成太阳码：{}",sunCodeUrl);
        if(StringUtils.isBlank(sunCodeUrl)){
            return ResultModel.fail("生成太阳码失败");
        }

//        String goodsCardUrl=redisUtil.get(RedisCode.getGoodsCard(commodityInfoEntity.getSpecId(),request.getId()));
        String goodsCardUrl;
        if(true){
            String url=commodityInfoEntity.getCoverImg();
            if(StringUtils.isBlank(url)){
                url=commodityInfoEntity.getUrl();
            }
            UserModel userModel=userMapper.selectByPrimaryKey(request.getId().intValue());
            GoodsPosterEntity goodsPosterEntity=new GoodsPosterEntity();
            goodsPosterEntity.setImagePath(cardPosterConfig.getGoodsCard());
            goodsPosterEntity.setGoodsUrl(url);
            goodsPosterEntity.setMoney(commodityInfoEntity.getPrice()/100.0+"");
            goodsPosterEntity.setGoodsName(commodityInfoEntity.getGoodsName());
            goodsPosterEntity.setUserName(new String(Base64.getDecoder().decode(userModel.getNickeName())));
            goodsPosterEntity.setUserLogo(userModel.getAvatarUrl());
            goodsPosterEntity.setSunCodeUrl(sunCodeUrl);
            goodsCardUrl =ossUtil.uploadObjectOSS(imageGenerateUtil.goodsCard(goodsPosterEntity),"png");
            //redisUtil.set(RedisCode.getGoodsCard(commodityInfoEntity.getSpecId(),request.getId()),goodsCardUrl);
        }
        return ResultModel.success(goodsCardUrl);
    }
}
